#include "barrier.h"

namespace sprites
{
	Barrier::Barrier(Vector3D _pos, MatterType _type, float boundRadius)
		: Sprite(_pos, _type, boundRadius, 1.0f), blockCols(10), blockRows(5)
	{
		initBlocksArray();
		build();
	}
	Barrier::Barrier(Vector3D _pos, MatterType _type, float boundRadius, float scale)
		: Sprite(_pos, _type, boundRadius, scale), blockCols(10), blockRows(5)
	{
		initBlocksArray();
		build();
	}

	Barrier::~Barrier()
		{
			//memory leaks make me sad :(
			//free up that memory to prevent those leaky memories.
			killBlocks();
			free(blocks);
			root->destroy();
		}

	/*
	 * This routine is crazy.  The general idea was inspired by a random forum post I found,
	 * but I did code all of this.
	 */
	void Barrier::build()
		{
			int rowIter, colIter;
			float x, y;
			float z = pos.Z;
			Brick* brick;
			for(rowIter = 0; rowIter < blockRows; rowIter++)
			{
			for(colIter = 0; colIter < blockCols; colIter++)
				{
					if(colIter > 1 && colIter < 8 && rowIter < 2)
					{
						//this is used to create the space for the barriers
						blocks[rowIter][colIter] = 0;
					}
					else 
					{
						x = pos.X + colIter*0.25;
						y = pos.Y + rowIter*0.25;
						brick = new Brick(Vector3D(x, y, z), collisions::BARRIER, 1.0f, scale);
						blocks[rowIter][colIter] = brick;
					}
				}
			}
		}

	void Barrier::initBlocksArray()
		{
			int rowIter;
			blocks = (Brick ***) malloc(blockRows * sizeof(Brick));
			for(rowIter = 0; rowIter < blockRows; rowIter++)
			{
				blocks[rowIter] = (Brick **) malloc(blockCols * sizeof(Brick));
			}
		}
	void Barrier::killBlocks()
		{
			int rowIter, colIter;
			for(rowIter = 0; rowIter < blockRows; rowIter++)
			{
				for(colIter = 0; colIter < blockCols; colIter++)
				{
					blocks[rowIter][colIter]->~Brick();
				}
			}
		}

	//TO REIMPLEMENT
	BindingSphere Barrier::getBindingSphere()
	{
		return bound;
	}

	std::vector<BindingSphere> Barrier::getBindingShapes()
	{
		vector<BindingSphere> jad = vector<BindingSphere>();
		for(int j = 0; j < blockRows; j++)
		{
			for(int i = 0; i < blockCols; i++)
			{
				if(blocks[j][i] != 0 && !blocks[j][i]->isDead())
					jad.push_back(blocks[j][i]->getBindingSphere());
			}
		}
		return jad;
	}


	void Barrier::handleCollision(MatterType oType, BindingSphere sphere)
	{
		switch(oType)
		{
		case collisions::BARRIER:
			throw "huh?!";
			break;
		case collisions::SHIPBULLET :
			destroyBricks(sphere);
			//blow up some of the barrier
			break;
		case collisions::INVADERBULLET :
			destroyBricks(sphere);
			//blow up some of the barrier
			break;
		case collisions::INVADER :
			//do nothing
			break;
		case collisions::SHIP :
			//huh? O.o
			break;
		}
	}

	void Barrier::destroyBricks(BindingSphere sphere)
	{
		for(int j = 0; j < blockRows; j++)
		{
			for(int i = 0; i < blockCols; i++)
			{
				if(blocks[j][i] != 0 && !blocks[j][i]->isDead() && blocks[j][i]->getBindingSphere().collidesWith(sphere))
				{
					blocks[j][i]->destroyed();

					if(j > 0 && blocks[j-1][i] != 0)
						blocks[j-1][i]->destroyed();

					if(j < blockRows - 1 && blocks[j+1][i] != 0)
						blocks[j+1][i]->destroyed();

					if(i > 0 && blocks[j][i-1] != 0)
						blocks[j][i-1]->destroyed();

					if(i < blockCols - 1 && blocks[j][i+1] != 0)
						blocks[j][i+1]->destroyed();
					break;
				}
			}
		}
	}

	void Barrier::draw()
	{
		for(int j = 0; j < blockRows; j++)
		{
			for(int i = 0; i < blockCols; i++)
			{
				if(blocks[j][i] != 0 && !blocks[j][i]->isDead())
					blocks[j][i]->draw();
			}
		}
	}

	void Barrier::reset()
	{
		for(int j = 0; j < blockRows; j++)
		{
			for(int i = 0; i < blockCols; i++)
			{
				if(blocks[j][i] != 0)
					blocks[j][i]->revive();
			}
		}
	}
}